/**
 * 
 */
package edu.arizona.bio5.onto.decomposition.persistent.xml;

import org.w3c.dom.Document;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.Database;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.XMLResource;

import edu.arizona.bio5.onto.decomposition.persistent.ADPersistenceException;
import edu.arizona.bio5.onto.decomposition.persistent.AtomLoader;

/**
 * @author Pavel Klinov
 *
 */
public class XMLDBLoader extends XMLADLoader {

	private final String mDatabaseURI;
	private final String mOntologyName;
	private final Database mDB;
	private Collection mRootCollection;
	private final String mUser;
	private final String mPwd;
	
	public XMLDBLoader(final String dbURI, final String ontoName, final String username, final String password) throws ADPersistenceException {
		mDatabaseURI = dbURI;
		mOntologyName = ontoName;
		mUser = username;
		mPwd = password;
		
		final String driver = "org.exist.xmldb.DatabaseImpl";
		// initialize database driver
		try {
			Class<?> cl = Class.forName(driver);
			
			mDB = (Database) cl.newInstance();
			DatabaseManager.registerDatabase(mDB);
			
		} catch (Throwable e) {
			throw !(e instanceof ADPersistenceException) ? new ADPersistenceException(e) : (ADPersistenceException)e;
		}
	}
	
	@Override
	protected void prepare() throws ADPersistenceException {
		try {
			mRootCollection = DatabaseManager.getCollection(mDatabaseURI + "/" + mOntologyName, mUser, mPwd);
			
			assertRootCollection();
		} catch (XMLDBException e) {
			//Can only die...
			throw new ADPersistenceException(e);
		}
	}

	@Override
	protected void finish() {
		try {
			if (mRootCollection != null) {
				mRootCollection.close();
				mRootCollection = null;
			}
		} catch (XMLDBException e) {
			// Fuck it
		} 
	}

	@Override
	protected Document loadDocument(String docName) throws ADPersistenceException {
		try {
			return (Document) ((XMLResource)mRootCollection.getResource(docName)).getContentAsDOM();
		} catch (XMLDBException e) {
			throw new ADPersistenceException(e);
		}
	}

	@Override
	protected String loadDocumentAsString(String docName) throws ADPersistenceException {
		try {
			return mRootCollection.getResource(docName).getContent().toString();
		} catch (XMLDBException e) {
			throw new ADPersistenceException(e);
		}
	}

	@Override
	protected AtomLoader createXMLAtomLoader() throws ADPersistenceException {
		try {
			
			Collection atomColl = mRootCollection.getChildCollection("atoms");
			
			return new XMLDBAtomLoader(atomColl);
		} catch (XMLDBException e) {
			throw new ADPersistenceException(e);
		}
	}

	private void assertRootCollection() throws ADPersistenceException {
		if (mRootCollection == null) {
			throw new ADPersistenceException("Can't get the root collection of the XML DB");
		}
		/*else {
			try {
				for (String child : mRootCollection.listChildCollections()) {
					System.out.println(child);
				}
			} catch (XMLDBException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}*/
	}	
}